package com.wzz.controller;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wzz.entity.*;
import com.wzz.mapper.ReqExamMapper;
import com.wzz.service.*;
import com.wzz.utils.JwtUtils;
import com.wzz.utils.RedisUtil;
import com.wzz.vo.*;
import io.jsonwebtoken.lang.Collections;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.Synchronized;
import org.apache.commons.collections.map.HashedMap;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.sql.Wrapper;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@RestController
@RequiredArgsConstructor
@Api(tags = "三个角色公共的相关接口")
@RequestMapping(value = "/public")
public class PublicController {

    private final NoticeService noticeService;

    private final ExamService examService;

    private final QuestionBankService questionBankService;

    private final RedisUtil redisUtil;
    private final SnatchService snatchService;
    private final ReqExamService reqExamService;
    private final ReqExamMapper reqExamMapper;
    private final UserService userService;
    private final ExamRecordService examRecordService;

    @PostMapping("/getExamInfo")
    @ApiOperation("根据信息查询答题的信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "examQueryVo", value = "答题信息查询vo对象", required = true, dataType = "examQueryVo", paramType = "body")
    })
    public CommonResult<PageResponse<Exam>> getExamInfo(@RequestBody ExamQueryVo examQueryVo,HttpServletRequest request) {
        TokenVo tokenVo = JwtUtils.getUserInfoByToken(request);
        String username = tokenVo.getUsername();
        User user = userService.getUserByUsername(username);

        PageResponse<Exam> examPage = examService.getExamPage(examQueryVo);
        examPage.getData().stream().forEach(exam->{
            QueryWrapper<ReqExam> query=new QueryWrapper();
            query.eq("userid",user.getId());
            query.eq("examid",exam.getExamId());
            List<ReqExam> reqExamList = reqExamMapper.selectList(query);
            if(!Collections.isEmpty(reqExamList)){
                exam.setFlag(reqExamList.get(0).getFlag());
            }else{
                exam.setFlag("0");
            }
            QueryWrapper<ExamRecord> queryRecord=new QueryWrapper<>();
            queryRecord.eq("user_id",user.getId());
            queryRecord.eq("exam_id",exam.getExamId());
            List<ExamRecord> recordList = examRecordService.list(queryRecord);
            if(recordList.size() > 0){
                exam.setRecod("1");
            }else{
                exam.setRecod("0");
            }
        });

        return CommonResult.<PageResponse<Exam>>builder()
                .data(examPage)
                .build();
    }

    @GetMapping("/getExamInfoById")
    @ApiOperation("根据答题id查询答题的信息和题目列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "examId", value = "答题id", required = true, dataType = "int", paramType = "query")
    })
    public CommonResult<AddExamByQuestionVo> getExamInfoById(@RequestParam Integer examId) {
        return CommonResult.<AddExamByQuestionVo>builder()
                .data(examService.getExamInfoById(examId))
                .build();
    }

    @GetMapping("/allExamInfo")
    @ApiOperation("查询答题所有信息")
    public CommonResult<List<Exam>> allExamInfo() {
        return CommonResult.<List<Exam>>builder()
                .data(examService.list(null))
                .build();
    }

    @GetMapping("/getBankHaveQuestionSumByType")
    @ApiOperation("获取题库中所有题目类型的数量")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bankName", value = "题库名称", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageNo", value = "页面数", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小", required = true, dataType = "int", paramType = "query"),
    })
    public CommonResult<PageResponse<BankHaveQuestionSum>> getBankHaveQuestionSumByType(@RequestParam(required = false) String bankName,
                                                                                        Integer pageNo, Integer pageSize) {
        return CommonResult.<PageResponse<BankHaveQuestionSum>>builder()
                .data(questionBankService.getBankHaveQuestionSumByType(bankName, pageNo, pageSize))
                .build();
    }

    @GetMapping("/getQuestionByBankIdAndType")
    @ApiOperation("根据题库id和题目类型获取题目信息 type(1单选 2多选 3判断)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bankId", value = "题库id", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "题目类型", required = true, dataType = "int", paramType = "query"),
    })
    public CommonResult<List<QuestionVo>> getQuestionByBankIdAndType(Integer bankId, Integer type) {
        return CommonResult.<List<QuestionVo>>builder()
                .data(questionBankService.getQuestionByBankIdAndType(bankId, type))
                .build();
    }

    @GetMapping("/getQuestionByBank")
    @ApiOperation("根据题库获取所有的题目信息(单选,多选,判断题)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bankId", value = "题库id", required = true, dataType = "int", paramType = "query")
    })
    public CommonResult<List<QuestionVo>> getQuestionByBank(Integer bankId) {
        return CommonResult.<List<QuestionVo>>builder()
                .data(questionBankService.getQuestionsByBankId(bankId))
                .build();
    }

    @GetMapping("/getCurrentNewNotice")
    @ApiOperation("获取当前系统最新的公告")
    public CommonResult<String> getCurrentNewNotice() {
        return CommonResult.<String>builder()
                .data(noticeService.getCurrentNotice())
                .build();
    }


    @GetMapping("/startKs")
    @ApiOperation("答题开始")
        public CommonResult<String> startKs(String examId,HttpServletRequest request) {
        TokenVo tokenVo = JwtUtils.getUserInfoByToken(request);
        String username = tokenVo.getUsername();
        User user = userService.getUserByUsername(username);

        QueryWrapper<ExamRecord> queryRecord=new QueryWrapper<>();
        queryRecord.eq("userId",user.getId());
        queryRecord.eq("examId",examId);
        List<ExamRecord> recordList = examRecordService.list(queryRecord);
        if(recordList.size() > 0){
            return CommonResult.<String>builder()
                    .data("已经参加过考试!")
                    .build();
        }
        // 点击答题开始，放入缓存时间
        redisUtil.set(examId, "startKs", 60);
        return CommonResult.<String>builder()
                .data("开始成功！")
                .build();
    }

    @PostMapping("/startKs1")
    @ApiOperation("答题开始")
    public CommonResult<Map<String,String>> startKs(@RequestBody @Valid Snatch snatch) {
        Map<String,String> map=new HashedMap();
        Object o = redisUtil.get(snatch.getExamid() + "qqqq");
        redisUtil.set(snatch.getExamid() + "qqqq", "qqq");
        long expire1 = redisUtil.getExpire(snatch.getExamid() + "qqq");
        if(expire1==-2) {
            if (Objects.isNull(o)) {
                redisUtil.set(snatch.getExamid() + "qqq", "qqq", 20);
                map.put("isOk", "0");
                map.put("readTime","20");
            } else {
                map.put("isOk", "1");
                map.put("readTime","0");
            }
        }else{
            long expire = redisUtil.getExpire(snatch.getExamid() + "qqq");
            map.put("isOk", "1");
            map.put("readTime",expire+"");
        }
        System.out.println(map.get("readTime"));
        return CommonResult.<Map<String,String>>builder()
                .data(map)
                .build();
    }

    @GetMapping("/getStartExamTime")
    @ApiOperation("获取当前答题时间的剩余时间数")
    public CommonResult<Long> getStartExamTime(String examId) {
        long expire = redisUtil.getExpire(examId);
        return CommonResult.<Long>builder().data(expire).build();
    }


    @PostMapping("/qd")
    @ApiOperation("抢答")
    public CommonResult<Map<String,String>> qd(@RequestBody @Valid Snatch snatch) {
        Map<String, String> map = getExpireDate(snatch.getExamid(), snatch.getQuestionid());
        return CommonResult.<Map<String,String>>builder()
                .data(map)
                .build();
    }

    @Synchronized
    public  Map<String,String> getExpireDate(@RequestParam("examId") String examId,@RequestParam("questionId") String questionId){
        Map<String,String> map=new HashMap<>();
        Object o= redisUtil.get(examId + questionId + "q");
        if(Objects.isNull(o)){
            redisUtil.set(examId + questionId + "q","");
            map.put("isOk","0");
        }else{
            map.put("isOk","1");
            // 是否已答題
            QueryWrapper<Snatch> queryWrap = new QueryWrapper();
            queryWrap.eq("examid",examId);
            queryWrap.eq("questionid",questionId);
            Snatch snatch = snatchService.getOne(queryWrap);
            if(Objects.isNull(snatch)){
                map.put("isAws","1");
            }else{
                map.put("isAws","0");
                map.put("nextTime",redisUtil.getExpire(examId+ questionId + "time")+"");
            }
        }
        return map;
    }

    @GetMapping("/nextTime")
    @ApiOperation("下一題的時間")
    public CommonResult<String> nextTime(String examId,String number) {
        // 点击答题开始，放入缓存时间
        redisUtil.set(examId+number, "next", 10);
        return CommonResult.<String>builder()
                .data("5")
                .build();
    }

}
